import base64

from django.db.models import Q, Sum, Count
from django.http import JsonResponse
from django.utils.datastructures import MultiValueDictKeyError
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response

from business import models
from business.business_permissions import ShopPermission, CustomerPermission, RiderPermission
from business.models import Item, Order, Comment
from business.serializers import ItemSerializer, ItemIdSerializer, OrderIdSerializer, CommentSerializer
from db_backfront_23.settings import MEDIA_ROOT, ITEM_IMAGE_DIR
from user.models import User


# Create your views here.
@api_view(['POST'])
@permission_classes([ShopPermission, ])
def upload_item(request):
    serializer = ItemSerializer(request.data)
    if serializer.is_valid():
        instance = serializer.save()  # 调用create方法
        return JsonResponse({"id": instance.id})
    return JsonResponse({"id": -1})  # 创建出错


@api_view(['PUT'])
@permission_classes([ShopPermission, ])
def edit_item(request):
    item_id = request.data['id']
    try:
        instance = Item.objects.get(id=item_id, shop=request.user)
    except Exception:
        return JsonResponse({"success": False})
    serializer = ItemSerializer(instance=instance, data=request.data)
    if serializer.is_valid():
        serializer.save()
        return JsonResponse({"success": True})
    return JsonResponse({"success": False})


@api_view(['POST', ])
@permission_classes([ShopPermission, ])
def delete_item(request):
    try:
        item_id = request.data['id']
        item = Item.objects.get(id=item_id)
        item.delete()
    except Exception:
        return JsonResponse({"success": False})
    return JsonResponse({"success": True})



@api_view(['POST'])
@permission_classes([ShopPermission, ])
def announce_order(request):  # 发布订单
    order_id = request.data['id']
    instance = Order.objects.get(id=order_id)
    instance.state = models.WAITING
    instance.save()
    return JsonResponse({"success": True})


# TODO
@api_view(['GET'])
def search_item(request):
    user = User.objects.get(username=request.user.username)
    keyword = request.GET.get('keyword')
    rank_type = request.GET.get('rank_type')
    keyword_list = keyword.split()
    queries = [Q(name__icontains=word) | Q(info__icontains=word) for word in keyword_list]
    if len(queries) == 0:
        query = Q()
    else:
        query = queries.pop()
        for item in queries:
            query |= item
    if user.user_type == 'C':  # 顾客
        datas = Item.objects.annotate(sales=Count('order')).filter(query).values()
    else:  # 商家
        datas = Item.objects.annotate(sales=Count('order')).filter(query, shop=request.user).values()
    if "P" in rank_type:
        a_d = rank_type[rank_type.find("P") + 1]
        if a_d == "A":
            datas = datas.order_by("single_price")  # 升序
        else:
            datas = datas.order_by("-single_price")  # 降序
    if "S" in rank_type:
        a_d = rank_type[rank_type.find("S") + 1]
        if a_d == "A":
            datas = sorted(datas, key=get_sales)
        else:
            datas = sorted(datas, key=get_sales, reverse=True)
    if "R" in rank_type:
        a_d = rank_type[rank_type.find("R") + 1]
        if a_d == "A":
            datas = sorted(datas, key=get_rating)
        else:
            datas = sorted(datas, key=get_rating, reverse=True)
    serializer = ItemIdSerializer(list(datas), many=True)
    return Response(serializer.data)


# TODO
def get_sales(item):
    return item['sales']

# TODO
def get_rating(item):
    item_id = item['id']
    instance = Item.objects.get(id=item_id)
    comment_set = instance.comment_set
    comment_num = comment_set.count()  # 求出评论数
    rating = 0
    if comment_num != 0:
        result = comment_set.aggregate(rating_sum=Sum('rating'))
        rating = result['rating_sum'] / comment_num
    return rating


@api_view(['GET'])
def global_search_item(request):
    keyword = request.GET.get('keyword')
    rank_type = request.GET.get('rank_type')
    keyword_list = keyword.split()
    queries = [Q(name__icontains=word) | Q(info__icontains=word) for word in keyword_list]
    if len(queries) == 0:
        query = Q()
    else:
        query = queries.pop()
        for item in queries:
            query |= item
    datas = Item.objects.annotate(sales=Count('order')).filter(query).values()
    if "P" in rank_type:
        a_d = rank_type[rank_type.find("P") + 1]
        if a_d == "A":
            datas = datas.order_by("single_price")  # 升序
        else:
            datas = datas.order_by("-single_price")  # 降序
    if "S" in rank_type:
        a_d = rank_type[rank_type.find("S") + 1]
        if a_d == "A":
            datas = sorted(datas, key=get_sales)
        else:
            datas = sorted(datas, key=get_sales, reverse=True)
    if "R" in rank_type:
        a_d = rank_type[rank_type.find("R") + 1]
        if a_d == "A":
            datas = sorted(datas, key=get_rating)
        else:
            datas = sorted(datas, key=get_rating, reverse=True)
    serializer = ItemIdSerializer(list(datas), many=True)
    return Response(serializer.data)



# TODO
@api_view(['GET'])
def item_detail(request):
    item_id = request.GET.get('id')
    instance = Item.objects.get(id=item_id)
    sales, rating = get_stat_info(item_id)
    if instance.shop.shop_profile:
        return JsonResponse(
            {
                "name": instance.name,
                "single_price": instance.single_price,
                "info": instance.info,
                "shop": instance.shop.id,
                "shop_name": instance.shop.shop_profile.shop_name,
                "sales": sales,
                "rating": rating,
            }
        )
    else:  # 如果没有profile
        return JsonResponse(
            {
                "name": instance.name,
                "single_price": instance.single_price,
                "info": instance.info,
                "shop": instance.shop.id,
                "shop_name": None,
                "sales": sales,
                "rating": rating,
            }
        )


# TODO
def get_stat_info(item_id):
    item = Item.objects.get(id=item_id)
    sales = item.order_set.count()
    comment_set = item.comment_set
    comment_num = comment_set.count()  # 求出评论数
    rating = 0
    if comment_num != 0:
        result = comment_set.aggregate(rating_sum=Sum('rating'))
        rating = result['rating_sum'] / comment_num
    return sales, rating


@api_view(['POST'])
@permission_classes([CustomerPermission, ])
def create_order(request):
    # 顾客创建订单的API
    try:
        shop_id = request.data['shop']
        num = request.data['num']
        item_id = request.data['good']
        address = request.data['address']
        phone_num = request.data['phone_num']
        Order.objects.create(
            item_id=item_id,
            num=num,
            state=models.PREPARING,
            rider=None,
            shop_id=shop_id,
            customer_id=request.user.id,
            address=address,
            phonenum=phone_num
        )
    except Exception:
        return JsonResponse({"success": False})
    return JsonResponse({"success": True})


@api_view(['GET'])
def get_orders(request):
    # 查看订单列表的API
    user = User.objects.get(username=request.user.username)
    if user.user_type == 'C':
        orders = Order.objects.filter(  # 拿到所有自己的订单
            customer_id=user.id
        ).values().order_by("create_time")
        serializer = OrderIdSerializer(list(orders), many=True)
        return Response(serializer.data)
    elif user.user_type == 'S':
        # 拿到所有自己的订单
        orders = Order.objects.filter(
            shop_id=user.id
        ).values().order_by("create_time")
        serializer = OrderIdSerializer(list(orders), many=True)
        return Response(serializer.data)
    else:  # 'R'
        # 返回所有状态未WAITING的订单，以供骑手挑选接单
        orders = Order.objects.filter(
            rider_id=user.id
        ).values().order_by("create_time")
        serializer = OrderIdSerializer(list(orders), many=True)
        return Response(serializer.data)


@api_view(['GET'])
@permission_classes([RiderPermission])
def get_waiting_orders(request):
    # 获取等待接单的订单的id列表
    orders = Order.objects.filter(
        state=models.WAITING
    ).values().order_by("create_time")
    serializer = OrderIdSerializer(list(orders), many=True)
    return Response(serializer.data)


@api_view(['POST'])
@permission_classes([RiderPermission])
def receive_order(request):
    # 接单
    try:
        order_id = request.data['id']
        order = Order.objects.get(id=order_id)
    except Exception:
        return JsonResponse({"success": False})
    order.rider = request.user
    order.state = models.DELIVERING
    order.save()
    return JsonResponse({"success": True})


@api_view(['POST'])
@permission_classes([RiderPermission])
def deliver_order(request):
    # 送达
    try:
        order_id = request.data['id']
        order = Order.objects.get(id=order_id)
    except Exception:
        return JsonResponse({"success": False})
    order.state = models.ARRIVED
    order.save()
    return JsonResponse({"success": True})


@api_view(['POST'])
@permission_classes([CustomerPermission])
def finish_order(request):
    # 订单完成(由顾客完成)
    try:
        order_id = request.data['id']
        order = Order.objects.get(id=order_id)
    except Exception:
        return JsonResponse({"success": False})
    order.state = models.FINISHED
    order.save()
    return JsonResponse({"success": True})


@api_view(['GET'])
def order_detail(request):
    order_id = request.GET.get('id')
    order = Order.objects.get(id=order_id)
    item = order.item
    if order.rider is None:
        return JsonResponse(
            {
                "sum_price": item.single_price * order.num,
                "state": order.state,
                "rider": None,
                "shop": order.shop.id,
                "customer": order.customer.id,
                "item": item.id,
                "address": order.address,
                "phone_num": order.customer.phone_num,
                "create_time": order.create_time.strftime("%Y-%m-%d %H:%M:%S")
            }
        )
    return JsonResponse(
        {
            "sum_price": item.single_price * order.num,
            "state": order.state,
            "rider": order.rider.id,
            "shop": order.shop.id,
            "customer": order.customer.id,
            "item": item.id,
            "address": order.address,
            "phone_num": order.customer.phone_num,
            "create_time": order.create_time.strftime("%Y-%m-%d %H:%M:%S")
        }
    )


@api_view(['PUT'])
@permission_classes([ShopPermission, ])
def upload_item_image(request):
    try:
        new_image = request.FILES['item_image']
    except MultiValueDictKeyError:  # 未上传文件
        return Response({'success': False})
    item = Item.objects.get(id=request.data['item_id'])
    if item.item_image:  # 判断原本是否有商品图片
        item.item_image.delete()  # 删除旧图片
    item.item_image = new_image
    item.save()  # 保存新商品图片
    return JsonResponse({'success': True})


@api_view(['GET'])
def get_item_image(request):
    item_id = request.GET.get('id')
    filename = str(item_id) + '_item_image' + '.jpg'
    path = MEDIA_ROOT + '/' + ITEM_IMAGE_DIR + '/' + filename
    try:
        with open(path, 'rb') as img_file:
            image_data = img_file.read()
            base64_encoded_image = base64.b64encode(image_data).decode('utf-8')
            return Response({"image": base64_encoded_image})
    except FileNotFoundError:
        return Response(status=404)


@api_view(['POST'])
@permission_classes([CustomerPermission, ])
def send_comment(request):
    try:
        order_id = request.data['id']
        order = Order.objects.get(id=order_id)
        item = order.item
        Comment.objects.create(
            rating=request.data['rating'],
            comment=request.data['comment'],
            sender_id=request.user.id,
            item_id=item.id
        )
        order.state = models.COMMENTED
        order.save()
    except Exception:
        return Response({"success": False})
    return Response({"success": True})


@api_view(['GET'])
def get_comments(request):
    item_id = request.GET.get('id')
    comments = Comment.objects.filter(item_id=item_id).values().order_by("create_time")
    serializer = CommentSerializer(list(comments), many=True)
    return Response(serializer.data)


# TODO
@api_view(['GET'])
def get_shop_state(request):
    shop_id = request.GET.get('id')
    shop = User.objects.get(id=shop_id)
    if shop.shop_profile.is_working:
        return JsonResponse({'status': 'O'})
    else:
        return JsonResponse({'status': 'C'})


# TODO
@api_view(['POST'])
@permission_classes([ShopPermission])
def change_shop_state(request):
    shop = User.objects.get(id=request.user.id)
    shop_profile = shop.shop_profile
    if request.data['status'] == 'O':
        shop_profile.is_working = True
    else:
        shop_profile.is_working = False
    shop_profile.save()
    return JsonResponse({'success': True})
